package com.store.daoimpl;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.store.dao.GeneralDao;
import com.stroe.util.HibernateSessionFactory;
import com.stroe.util.Page;

public class GeneralDaoImpl<T extends Serializable> extends HibernateDaoSupport
		implements GeneralDao<T> {
	private Class<T> entityClass;

	@SuppressWarnings("unchecked")
	public GeneralDaoImpl() {
		this.entityClass = null;
		@SuppressWarnings("rawtypes")
		Class c = getClass();
		Type type = c.getGenericSuperclass();
		if (type instanceof ParameterizedType) {
			Type[] p = ((ParameterizedType) type).getActualTypeArguments();
			this.entityClass = (Class<T>) p[0];
		}
	}

	@Override
	public boolean save(T t) {
		Session session = null;
		try {
			session = HibernateSessionFactory.getSession();
			session.beginTransaction();
			session.save(t);
			session.getTransaction().commit();
			return true;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (session != null) {
				session.close();
			}
		}
		return false;
	}

	@Override
	public boolean update(T t) {
		Session session = null;
		try {
			session = HibernateSessionFactory.getSession();
			session.clear();
			session.beginTransaction();
			session.update(t);
			session.getTransaction().commit();
			return true;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (session != null) {
				session.close();
			}
		}
		return false;
	}

	@Override
	public boolean delete(T t) {
		Session session = null;
		try {
			session = HibernateSessionFactory.getSession();
			session.clear();
			session.beginTransaction();
			session.delete(t);
			session.getTransaction().commit();
			return true;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (session != null) {
				session.close();
			}
		}
		return false;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<T> getTs(Page page, Map<String, Object> map) {
		List<T> list = null;
		Session session = null;
		try {
			session = HibernateSessionFactory.getSession();
			Criteria criteria = session.createCriteria(entityClass);
			if (map != null && map.size() > 0) {
				Set<Entry<String, Object>> set = map.entrySet();
				Iterator<Entry<String, Object>> iterator = set.iterator();
				while (iterator.hasNext()) {
					Entry<String, Object> entry = iterator.next();
					criteria.add(Restrictions.eq(entry.getKey(),
							entry.getValue()));
				}
			}
			if (page != null) {
				criteria.setFirstResult(page.getStart());
				criteria.setMaxResults(page.getRows());
			}
			list = criteria.list();
			return list;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public long getTotal(Map<String, Object> map) {
		Session session = null;
		try {
			session = HibernateSessionFactory.getSession();
			Criteria criteria = session.createCriteria(entityClass);
			criteria.setProjection(Projections.rowCount());
			return (Long) criteria.uniqueResult();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (session != null) {
				session.close();
			}
		}
		return 0;
	}

}
